package cn.edu.tju.elm.controller;

import cn.edu.tju.core.model.HttpResult;
import cn.edu.tju.core.model.ResultCodeEnum;
import cn.edu.tju.elm.controller.dto.BankCardBindDto;
import cn.edu.tju.elm.controller.dto.BankCardUpdateDto;
import cn.edu.tju.elm.controller.dto.PaymentDto;
import cn.edu.tju.elm.controller.dto.RechargeDto;
import cn.edu.tju.elm.model.BankCard;
import cn.edu.tju.elm.model.BankCardTransaction;
import cn.edu.tju.elm.service.BankCardService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 银行卡管理控制器
 */
@RestController
@RequestMapping("/api/bank-cards")
@Tag(name = "银行卡管理", description = "提供银行卡绑定、解绑、支付、查询等功能")
public class BankCardController {

    @Autowired
    private BankCardService bankCardService;

    @PostMapping("/bind")
    @Operation(summary = "绑定银行卡", description = "用户绑定新的银行卡")
    public HttpResult<BankCard> bindBankCard(@RequestBody BankCardBindDto bindDto) {
        try {
            // 将DTO转换为实体
            BankCard bankCard = new BankCard();
            bankCard.setCardNumber(bindDto.getCardNumber());
            bankCard.setCardType(bindDto.getCardType());
            bankCard.setBankName(bindDto.getBankName());
            bankCard.setCardholderName(bindDto.getCardholderName());
            bankCard.setPhone(bindDto.getPhone());
            bankCard.setBalance(bindDto.getBalance());
            bankCard.setCreditLimit(bindDto.getCreditLimit());
            bankCard.setRemark(bindDto.getRemark());
            
            BankCard savedCard = bankCardService.bindBankCard(bankCard);
            // 清除敏感信息
            savedCard.setCardNumber(null);
            return HttpResult.success(savedCard);
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.BAD_REQUEST, e.getMessage());
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "绑定银行卡失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/{cardId}")
    @Operation(summary = "解绑银行卡", description = "用户解绑银行卡")
    public HttpResult<String> unbindBankCard(
            @Parameter(description = "银行卡ID") @PathVariable Long cardId) {
        try {
            boolean success = bankCardService.unbindBankCard(cardId);
            if (success) {
                return HttpResult.success("银行卡解绑成功");
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "银行卡不存在");
            }
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.BAD_REQUEST, e.getMessage());
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "解绑银行卡失败: " + e.getMessage());
        }
    }

    @GetMapping("/my-cards")
    @Operation(summary = "获取我的银行卡列表", description = "获取当前用户的所有银行卡")
    public HttpResult<List<BankCard>> getMyBankCards() {
        try {
            List<BankCard> cards = bankCardService.getCurrentUserBankCards();
            // 清除敏感信息
            cards.forEach(card -> card.setCardNumber(null));
            return HttpResult.success(cards);
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.UNAUTHORIZED, e.getMessage());
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取银行卡列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/{cardId}")
    @Operation(summary = "获取银行卡详情", description = "根据ID获取银行卡详细信息")
    public HttpResult<BankCard> getBankCardById(
            @Parameter(description = "银行卡ID") @PathVariable Long cardId) {
        try {
            Optional<BankCard> cardOpt = bankCardService.getBankCardById(cardId);
            if (cardOpt.isPresent()) {
                BankCard card = cardOpt.get();
                // 清除敏感信息
                card.setCardNumber(null);
                return HttpResult.success(card);
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "银行卡不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取银行卡详情失败: " + e.getMessage());
        }
    }

    @PutMapping("/{cardId}/default")
    @Operation(summary = "设置默认银行卡", description = "设置指定银行卡为默认支付卡")
    public HttpResult<String> setDefaultBankCard(
            @Parameter(description = "银行卡ID") @PathVariable Long cardId) {
        try {
            boolean success = bankCardService.setDefaultBankCard(cardId);
            if (success) {
                return HttpResult.success("设置默认银行卡成功");
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "银行卡不存在");
            }
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.BAD_REQUEST, e.getMessage());
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "设置默认银行卡失败: " + e.getMessage());
        }
    }

    @GetMapping("/default")
    @Operation(summary = "获取默认银行卡", description = "获取当前用户的默认银行卡")
    public HttpResult<BankCard> getDefaultBankCard() {
        try {
            // 这里需要获取当前用户ID，简化处理
            List<BankCard> cards = bankCardService.getCurrentUserBankCards();
            Optional<BankCard> defaultCard = cards.stream()
                    .filter(BankCard::getIsDefault)
                    .findFirst();
            
            if (defaultCard.isPresent()) {
                BankCard card = defaultCard.get();
                // 清除敏感信息
                card.setCardNumber(null);
                return HttpResult.success(card);
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "未设置默认银行卡");
            }
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.UNAUTHORIZED, e.getMessage());
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取默认银行卡失败: " + e.getMessage());
        }
    }

    @PostMapping("/recharge")
    @Operation(summary = "银行卡充值", description = "向银行卡充值")
    public HttpResult<BankCard> rechargeBankCard(@RequestBody RechargeDto rechargeDto) {
        try {
            BankCard updatedCard = bankCardService.rechargeBankCard(rechargeDto.getCardId(), rechargeDto.getAmount());
            // 清除敏感信息
            updatedCard.setCardNumber(null);
            return HttpResult.success(updatedCard);
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.BAD_REQUEST, e.getMessage());
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "充值失败: " + e.getMessage());
        }
    }

    @PostMapping("/pay")
    @Operation(summary = "银行卡支付", description = "使用银行卡支付订单")
    public HttpResult<String> payWithBankCard(@RequestBody PaymentDto paymentDto) {
        try {
            boolean success = bankCardService.payWithBankCard(paymentDto.getCardId(), paymentDto.getAmount(), paymentDto.getOrderId());
            if (success) {
                return HttpResult.success("支付成功");
            } else {
                return HttpResult.failure(ResultCodeEnum.BAD_REQUEST, "支付失败");
            }
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.BAD_REQUEST, e.getMessage());
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "支付失败: " + e.getMessage());
        }
    }

    @GetMapping("/{cardId}/transactions")
    @Operation(summary = "获取银行卡交易记录", description = "获取指定银行卡的交易记录")
    public HttpResult<List<BankCardTransaction>> getBankCardTransactions(
            @Parameter(description = "银行卡ID") @PathVariable Long cardId) {
        try {
            List<BankCardTransaction> transactions = bankCardService.getBankCardTransactions(cardId);
            return HttpResult.success(transactions);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取交易记录失败: " + e.getMessage());
        }
    }

    @GetMapping("/transactions")
    @Operation(summary = "获取我的交易记录", description = "获取当前用户的所有交易记录")
    public HttpResult<List<BankCardTransaction>> getMyTransactions() {
        try {
            // 这里需要获取当前用户ID，简化处理
            List<BankCard> cards = bankCardService.getCurrentUserBankCards();
            if (cards.isEmpty()) {
                return HttpResult.success(List.of());
            }
            
            // 获取第一张银行卡的交易记录作为示例
            List<BankCardTransaction> transactions = bankCardService.getBankCardTransactions(cards.get(0).getId());
            return HttpResult.success(transactions);
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.UNAUTHORIZED, e.getMessage());
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取交易记录失败: " + e.getMessage());
        }
    }

    @PutMapping("/{cardId}")
    @Operation(summary = "更新银行卡信息", description = "更新银行卡的基本信息")
    public HttpResult<BankCard> updateBankCard(
            @Parameter(description = "银行卡ID") @PathVariable Long cardId,
            @RequestBody BankCardUpdateDto updateDto) {
        try {
            // 将DTO转换为实体
            BankCard bankCard = new BankCard();
            bankCard.setId(cardId);
            bankCard.setPhone(updateDto.getPhone());
            bankCard.setRemark(updateDto.getRemark());
            
            BankCard updatedCard = bankCardService.updateBankCard(bankCard);
            // 清除敏感信息
            updatedCard.setCardNumber(null);
            return HttpResult.success(updatedCard);
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.BAD_REQUEST, e.getMessage());
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "更新银行卡信息失败: " + e.getMessage());
        }
    }

    @GetMapping("/{cardId}/balance")
    @Operation(summary = "查询银行卡余额", description = "查询银行卡的可用余额")
    public HttpResult<BigDecimal> getBankCardBalance(
            @Parameter(description = "银行卡ID") @PathVariable Long cardId) {
        try {
            Optional<BankCard> cardOpt = bankCardService.getBankCardById(cardId);
            if (cardOpt.isPresent()) {
                BankCard card = cardOpt.get();
                BigDecimal availableAmount = card.getAvailableAmount();
                return HttpResult.success(availableAmount);
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "银行卡不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询余额失败: " + e.getMessage());
        }
    }
}
